<?php


namespace App\Services;


use App\Constants\IntegralLogTypeConstant;
use App\Constants\ModuleSlugConstant;
use App\Constants\TemplateMessageConstant;
use App\Constants\VipLogOperateTypeConstant;
use App\Exceptions\BusinessException;
use App\Jobs\Message\SendMessage;
use App\Models\Member;
use App\Models\MemberVipLog;
use Illuminate\Contracts\Cache\LockTimeoutException;
use Illuminate\Support\Facades\Cache;
use Illuminate\Support\Facades\DB;

class VipService
{
    public function checkMemberVip(int $memberId): bool
    {
        $member = Member::find($memberId);
        if (!$member) {
            throw new BusinessException('会员信息不存在', 40001);
        }

        if (!$member->is_vip) {
            return false;
        }

        $endTime = $member->vip_end_time;

        if (!$endTime) {
            return false;
        }

        return $endTime > time();
    }

    public function exchangeVip(int $memberId, int $day, int $integral)
    {
        $lock = Cache::lock('INTEGRAL_EXCHANGE_VIP_' . $memberId, 10);

        try {
            $lock->block(5);

            DB::beginTransaction();

            $member = Member::find($memberId);
            if (!$member) throw new BusinessException('用户不存在');

            if ($member->integral < $integral) throw new BusinessException('积分不足');

            $startTime = $member->is_vip ? $member->vip_end_time : time();
            $endTime = ($day * 24 * 3600) + $startTime;

            $member->update(['is_vip' => 1, 'vip_end_time' => $endTime]);

            MemberVipLog::create([
                'member_id'    => $memberId,
                'operate_type' => VipLogOperateTypeConstant::EXCHANGE,
                'content'      => sprintf('积分兑换%d天vip', $day),
            ]);

            app(IntegralService::class)->store(
                $member->mini_type,
                $memberId,
                -$integral,
                IntegralLogTypeConstant::TYPE_BY_EXCHANGE_VIP,
                sprintf('兑换%d天vip', $day)
            );

            SendMessage::dispatch($memberId, TemplateMessageConstant::VIP_OPEN_NOTICE, [
                'open_vip_date' => date('Y-m-d H:i:s')
            ]);

            DB::commit();
        } catch (LockTimeoutException $le) {
            throw new BusinessException('操作频繁,请稍后再试');
        } catch (\Throwable $e) {
            DB::rollBack();

            if (is_a($e, BusinessException::class)) throw $e;

            log_exception('积分兑换vip异常', $e);
            throw new BusinessException('兑换失败');
        } finally {
            optional($lock)->release();
        }
    }

    public function expireHandle(int $memberId): array
    {
        $member = Member::find($memberId);
        if (!$member) {
            return resultFailedReturn(sprintf('会员ID：%d 不存在', $memberId));
        }

        if (!$member->is_vip || !$member->vip_end_time) {
            return resultSuccessReturn();
        }

        if ($member->vip_end_time > time()) {
            return resultSuccessReturn();
        }

        $member->update(['is_vip' => 0]);
        MemberVipLog::create([
            'member_id'    => $memberId,
            'operate_type' => VipLogOperateTypeConstant::EXPIRE,
            'content'      => sprintf('vip于%s到期', date('Y-m-d H:i:s', $member->vip_end_time)),
        ]);

        SendMessage::dispatch($memberId, TemplateMessageConstant::VIP_EXPIRE_NOTICE);

        return resultSuccessReturn();
    }

    public function isNeedVipByRouteName($module, $routeName): bool
    {
        if (method_exists($this, $module)) {
            return $this->{$module}($routeName);
        }

        return false;
    }

    protected function health($routeName): bool
    {
        $settings = getSettings(ModuleSlugConstant::XW_MODULE);

        $arr = [
            'health.acu.info'             => $settings[ModuleSlugConstant::XW_ACU_MODULE] ?? 0,
            'health.meridian.info'        => $settings[ModuleSlugConstant::XW_ACU_MODULE] ?? 0,
            'health.breathe'              => $settings[ModuleSlugConstant::XW_BREATHE_MODULE] ?? 0,
            'health.disease.info'         => $settings[ModuleSlugConstant::XW_DISEASE] ?? 0,
            'health.disease.discern.info' => $settings[ModuleSlugConstant::XW_DISEASE_DISEASE] ?? 0,
            'health.plan.add'             => $settings[ModuleSlugConstant::XW_DISEASE] ?? 0,
            'health.plan.finish'          => $settings[ModuleSlugConstant::XW_DISEASE] ?? 0,

            'tcm.tcm_detail' => $settings[ModuleSlugConstant::TCM_MODULE] ?? 0,
            'tcm.book.chapter_details' => $settings[ModuleSlugConstant::TCM_MODULE] ?? 0,
        ];

        $needVip = $arr[$routeName] ?? 0;

        return $needVip == 1;
    }
}
